﻿//**************************************************************
//
// MoneyBaby Project - Open source payment processors for .NET
//
// Copyright 2007-2008 Marcus McConnell and BV Software
// www.CodePlex.com/MoneyBaby
//**************************************************************

using System;
using System.Collections.Generic;
using System.Text;

namespace BVSoftware.MoneyBaby
{
    /// <summary>
    /// Base implementation of the ICreditCardGateway interface
    /// </summary>
    public abstract class BaseCreditCardGateway<T> : ICreditCardGateway<T>, ICreditCardGateway
        where T: PaymentGatewaySettings, new()
    {
        private PaymentData<T> _PaymentData = null;
        private PaymentData<GenericPaymentGatewaySettings> _GenericPaymentData = null;
        
        // generate a unique ID for your processor for this method
        public abstract Guid GatewayId { get;}
        // a user friendly display name for your gateway
        public abstract string GatewayName { get; }


        // Use these properties to help out your users. Hide buttons
        // that your gateway doesn't support. No need to display a VOID
        // button to the user if they can't ever get a successful response.
        public abstract bool SupportsAuthorize { get; }
        public abstract bool SupportsCapture { get; }
        public abstract bool SupportsCharge { get; }
        public abstract bool SupportsRefund { get; }
        public abstract bool SupportsVoid { get; }

        public PaymentData<T> PaymentData 
        {
            get
            {
                if (_PaymentData == null)
                {
                    _PaymentData = new PaymentData<T>();
                }
                
                if (_GenericPaymentData != null)
                {
                    if (_GenericPaymentData.GatewaySettings != null)
                    {                                                
                        _PaymentData.GatewaySettings.PopulateFromGeneric(_GenericPaymentData.GatewaySettings);
                    }
                }
                return _PaymentData;
            }
        }

        // These methods do the real work of communicating with 
        // outside services based on the 
        public virtual TransactionResultData Authorize()
        {
            return ProcessCard(PaymentOperationType.Authorize, this.PaymentData);
        }
        public virtual TransactionResultData Capture()
        {
            return ProcessCard(PaymentOperationType.Capture, this.PaymentData);
        }
        public virtual TransactionResultData Charge()
        {
            return ProcessCard(PaymentOperationType.Charge, this.PaymentData);
        }
        public virtual TransactionResultData Refund()
        {
            return ProcessCard(PaymentOperationType.Refund, this.PaymentData);
        }
        public virtual TransactionResultData Void()
        {
            return ProcessCard(PaymentOperationType.Void, this.PaymentData);
        }

        protected abstract TransactionResultData ProcessCard(PaymentOperationType operationType, PaymentData<T> data);

        #region ICreditCardGateway Members

        PaymentData<GenericPaymentGatewaySettings> ICreditCardGateway.PaymentData
        {
            get
            {
                if (_GenericPaymentData == null)
                {
                    _GenericPaymentData = new PaymentData<GenericPaymentGatewaySettings>();
                }
                return _GenericPaymentData;
            }
        }

        #endregion
    }
}
